-
Notifications
You must be signed in to change notification settings - Fork 315
Enhanced routing envchange token support #3646
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feat/enhanced-routing
Are you sure you want to change the base?
Enhanced routing envchange token support #3646
Conversation
…g database value.
|
||
case TdsEnums.FEATUREEXT_ENHANCEDROUTINGSUPPORT: | ||
{ | ||
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.SqlInternalConnectionTds.OnFeatureExtAck|ADV> {0}, Received feature extension acknowledgement for ENHANCEDROUTINGSUPPORT", ObjectID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This log could be misleading if the data[0] != 1
. It implies that enhanced routing is enabled. Perhaps move it below line 3024 and include whether or not the feature is enabled as well.
UserServerName = string.Format(CultureInfo.InvariantCulture, "{0},{1}", routing.ServerName, routing.Port); | ||
} | ||
|
||
if (routing == null || routing.DatabaseName == null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would this statement be easier to understand if it were flipped?
// Always prefer a routing database name from the server, if supplied.
if (routing is not null && routing.DatabaseName is not null)
{
ResolvedDatabaseName = routing.DatabaseName;
}
else
{
ResolvedDatabaseName = userOptions.InitialCatalog;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe FeatureExtensionBehaviour
? It would be funny if you add a 4th member later :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this depend on how the server intends to respond? If EnableEnhancedRouting
is Disabled
or DoNotAcknowledge
, then support isn't enabled.
Maybe this flag should be called DidClientAskForEnhancedRouting
or something more succinct.
|
||
/// <summary> | ||
/// Database name to use at the routed location. | ||
/// Should only be set when doing enhanced routing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Setting this to a non-empty value will cause the server to include an enhanced routing ENVCHANGE token in the Login Response message. An empty value will include a legacy routing ENVCHANGE token."
// Arrange | ||
using TdsServer server = new(new() | ||
{ | ||
Log = Console.Out |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our tests should probably be using xUnit's ITestOutputHelper. Just an FYI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More so, I think we should be avoiding outputting random text during a test anyhow. But I think that's more of an existing issue that we're just not touching today.
DataSource = $"localhost,{router.EndPoint.Port}", | ||
Encrypt = false, | ||
ConnectTimeout = 10000 | ||
}).ConnectionString; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This arrange stuff is common to both tests. Can you pull it out?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll counter that this doesn't meet the rule of 3 for refactoring :)
{ | ||
DataSource = $"localhost,{router.EndPoint.Port}", | ||
Encrypt = false, | ||
ConnectTimeout = 10000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to test the case where InitialCatalog is explicitly specified by the app, and ignored during routing?
What about the cases where the server ignores or explicitly denies enhanced routing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally speaking it's pretty good. I have a handful of style comments and a couple general questions. But I don't think they're worth holding up the PR if you're not interested (I'm kinda breaking my own rules by not taking a super hard stance on it, tho)
break; | ||
|
||
case TdsEnums.ENV_ENHANCEDROUTING: | ||
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.SqlInternalConnectionTds.OnEnvChange|ADV> {0}, Received enhanced routing info", ObjectID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the tracing format we're trying to use going forward is the xyz | abc | whatever
format. But if the rest of the strings in this file are using the <abc...> asdfasdfads
format, then I won't complain.
|
||
if (routing == null || routing.DatabaseName == null) | ||
{ | ||
ResolvedDatabaseName = userOptions.InitialCatalog; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can has ternary ? 👉👈🥺
if (result != TdsOperationStatus.Done) | ||
{ | ||
return result; | ||
ushort newLength; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the whole deal with this big block o changes was you added scope {}
to this case? ... If we can avoid doing that that'd be better. But, if you reallly reallllly want to use a new variable in two scopes, I'll let it slide
/// <returns>Returns a <see cref="TdsOperationStatus"/> to indicate the status of the operation.</returns> | ||
private TdsOperationStatus TryProcessEnhancedRoutingToken(TdsParserStateObject stateObj, SqlEnvChange env) | ||
{ | ||
ushort newLength; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we inline the declarations here?
} | ||
|
||
/// <summary> | ||
/// Reads an enhanced routing token from the stream and populates the provided <see cref="SqlEnvChange"/> object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not required, but I think it'd be really nice to have a layout of the token structure in a comment either a remarks or comment in the body, maybe?
DataSource = $"localhost,{router.EndPoint.Port}", | ||
Encrypt = false, | ||
ConnectTimeout = 10000 | ||
}).ConnectionString; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll counter that this doesn't meet the rule of 3 for refactoring :)
|
||
// Act | ||
sqlConnection.Open(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: extra line here and in below instances
} | ||
} | ||
|
||
public class SimulatedServerFixture : IDisposable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please put top level classes in their own files
|
||
namespace Microsoft.SqlServer.TDS.Servers | ||
{ | ||
public enum FeatureExtensionEnablementTriState |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we do this as effectively with a bool?
?
// Create ack data (1 byte: IsEnabled) | ||
byte[] data = new byte[1]; | ||
|
||
if (EnableEnhancedRouting == FeatureExtensionEnablementTriState.Enabled) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can has ternary again?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact, can just do
byte[] data = EnableEnhancedRouting is FeatureExtensionEnablementTristate.Enabled
? [1]
: [0];
(and if we switch from tristate to bool? we could condense even more to)
byte[] data = IsEnhancedRoutingEnabled ? [1] : [0]
Description
Adds enhanced routing envchange support in service of #3641
Changes can be followed commit-by-commit for ease of review.
Issues
#3641
Testing
Adds simulated server tests to verify enhanced routing behavior.